package com.example.myapplication;

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.app.AlertDialog;
import android.app.Dialog;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.text.InputType;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;

import com.clj.fastble.BleManager;
import com.clj.fastble.callback.BleGattCallback;
import com.clj.fastble.callback.BleMtuChangedCallback;
import com.clj.fastble.callback.BleNotifyCallback;
import com.clj.fastble.callback.BleScanCallback;
import com.clj.fastble.callback.BleWriteCallback;
import com.clj.fastble.data.BleDevice;
import com.clj.fastble.exception.BleException;
import com.clj.fastble.scan.BleScanRuleConfig;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class MainActivity extends AppCompatActivity {
    private final String TAG = "MainActivity";
    private ArrayAdapter BleScanAdapter, BleConnAdapter;
    private Spinner spinner_ble_scan, spinner_ble_conn;
    private ArrayList ScanBleList = new ArrayList<BleDevice>();
    private ArrayList ConnBleList = new ArrayList<BleDevice>();
    private final String M_UART_SERVICE       = "86530006-43e6-47b7-9cb0-5fc21d4ae340";
    private final String M_UART_SERVICE_READ  = "86530007-43e6-47b7-9cb0-5fc21d4ae340";
    private final String M_UART_SERVICE_WRITE = "86530006-43e6-47b7-9cb0-5fc21d4ae340";
    private final int MTU = 247;        //mtu值
    private Dialog dialog;//输入地址对话框
    @Override
    protected void onStart() {
        super.onStart();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        disconnect_all();
    }
    private void disconnect_all() {

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        BleManager.getInstance().init(getApplication());
        BleManager.getInstance()
                .enableLog(true)
                .setReConnectCount(1, 5000)
                .setOperateTimeout(5000);

        BleScanRuleConfig scanRuleConfig = new BleScanRuleConfig.Builder()
                //.setServiceUuids(serviceUuids)      // 只扫描指定的服务的设备，可选
                .setDeviceName(true, "HEART_BELT")         // 只扫描指定广播名的设备，可选
                //.setDeviceMac("E5:4A:EC:04:9B:BF")                // 只扫描指定mac的设备，可选
                .setAutoConnect(false)               // 连接时的autoConnect参数，可选，默认false
                .setScanTimeOut(0)              // 扫描超时时间，可选，默认10秒
                .build();
        BleManager.getInstance().initScanRule(scanRuleConfig);

        spinner_ble_scan = findViewById(R.id.spinner_scan_result);
        spinner_ble_conn = findViewById(R.id.spinner_connect_list);

        BleScanAdapter = new ArrayAdapter<String>(this, androidx.appcompat.R.layout.support_simple_spinner_dropdown_item);
        spinner_ble_scan.setAdapter(BleScanAdapter);
        BleConnAdapter = new ArrayAdapter<String>(this, androidx.appcompat.R.layout.support_simple_spinner_dropdown_item);
        spinner_ble_conn.setAdapter(BleConnAdapter);
    }

    private void setMtu(BleDevice bleDevice, int mtu) {
        BleManager.getInstance().setMtu(bleDevice, mtu, new BleMtuChangedCallback() {
            @Override
            public void onSetMTUFailure(BleException exception) {
                Log.d(TAG, "setMTUFailure：" + exception.toString());
            }

            @Override
            public void onMtuChanged(int mtu) {
                Log.d(TAG, "MtuChanged: " + mtu);
                //设置MTU成功后，使能Notify
                enableNotification(bleDevice, M_UART_SERVICE, M_UART_SERVICE_READ);
            }
        });
    }

    private void enableNotification(BleDevice bleDevice, String uuid_service, String uuid_notify) {
        BleManager.getInstance().notify(bleDevice, uuid_service, uuid_notify,
                new BleNotifyCallback() {
                    @Override
                    public void onNotifySuccess() {
                        // 打开通知操作成功
                        Log.d(TAG, "Notify使能成功");
                    }

                    @Override
                    public void onNotifyFailure(BleException exception) {
                        // 打开通知操作失败
                        Log.d(TAG, "Notify使能失败");
                    }

                    @Override
                    public void onCharacteristicChanged(byte[] data) {
                        // 打开通知后，设备发过来的数据将在这里出现
                        Log.d(TAG,"bleRxData：0x"+bytesToHexString(data));
                    }
                });
    }
    public void scan_start(View view) {
        BleManager.getInstance().scan(new BleScanCallback() {
            @Override
            public void onScanStarted(boolean success) {
                Log.d(TAG, "scan success");
            }
            @Override
            public void onLeScan(BleDevice bleDevice) {
            }
            @Override
            public void onScanning(BleDevice bleDevice) {
                BleScanAdapter.add(bleDevice.getMac());
                ScanBleList.add(bleDevice);
            }
            @Override
            public void onScanFinished(List<BleDevice> scanResultList) {
            }
        });
    }
    public void scan_stop(View view) {
        BleScanAdapter.clear();
        ScanBleList.clear();
        BleManager.getInstance().cancelScan();
    }

    public void connect(View view) {
        if (spinner_ble_scan.getSelectedItem() != null) {
            BleDevice bleDevice = (BleDevice) ScanBleList.get(spinner_ble_scan.getSelectedItemPosition());
            BleManager.getInstance().connect(bleDevice, new BleGattCallback() {
                @Override
                public void onStartConnect() {
                }

                @Override
                public void onConnectFail(BleDevice bleDevice, BleException exception) {
                }
                @Override
                public void onConnectSuccess(BleDevice bleDevice, BluetoothGatt gatt, int status) {
                    if(!ConnBleList.contains(bleDevice))
                    {
                        BleConnAdapter.add(bleDevice.getMac());
                        ConnBleList.add(bleDevice);
                        //设置MTU就无法收发数据，存在bug
                        setMtu(bleDevice, MTU);
                    }
                }
                @Override
                public void onDisConnected(boolean isActiveDisConnected, BleDevice device, BluetoothGatt gatt, int status) {
                    ConnBleList.remove(device);
                    BleConnAdapter.remove(device.getMac());
                    BleManager.getInstance().stopNotify(device, M_UART_SERVICE, M_UART_SERVICE_READ);
                    BleManager.getInstance().disconnect(device);
                }
                @Override
                public void onPhyUpdate(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
                    //m_gatt.setPreferredPhy(txPhy, rxPhy, status);
                    Log.d(TAG, "txPhy：" + txPhy + "   rxPhy:" + rxPhy);
                }
                @Override
                public void onPhyRead(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
                    Log.d(TAG, "txPhy：" + txPhy + "   rxPhy:" + rxPhy);
                }
            });
        }
    }

    public void disconnect(View view) {
        BleDevice bleDevice = (BleDevice) ConnBleList.get(spinner_ble_conn.getSelectedItemPosition());
        BleManager.getInstance().stopNotify(bleDevice, M_UART_SERVICE, M_UART_SERVICE_READ);
        BleManager.getInstance().disconnect(bleDevice);
    }

    public void disconnect_all(View view) {
        for (int i = 0; i < ConnBleList.size(); i++) {
            BleManager.getInstance().stopNotify((BleDevice) ConnBleList.get(i), M_UART_SERVICE, M_UART_SERVICE_READ);
            BleManager.getInstance().disconnect((BleDevice) ConnBleList.get(i));
        }
        ConnBleList.clear();
        BleConnAdapter.clear();
    }

    public void sync_start(View view) {
        LayoutInflater factory = LayoutInflater.from(MainActivity.this);
        final View textEntryView = factory.inflate(R.layout.dialog, null);
        EditText tx_data1 = textEntryView.findViewById(R.id.et_tx1);
        EditText tx_data2 = textEntryView.findViewById(R.id.et_tx2);
        tx_data1.setInputType(InputType.TYPE_CLASS_NUMBER);
        tx_data2.setInputType(InputType.TYPE_CLASS_NUMBER);
        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
        builder.setTitle("请输入");
        builder.setIcon(android.R.drawable.ic_dialog_info);
        builder.setView(textEntryView);
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (!tx_data1.getText().toString().isEmpty() && !tx_data2.getText().toString().isEmpty()) {
                    byte sync_id = (byte) byteToUnsignedInt(Byte.parseByte(tx_data1.getText().toString()));
                    int sync_total = Integer.parseInt(tx_data2.getText().toString());
                    byte[] tx_buf = new byte[5];
                    tx_buf[0] = (byte) 0xAA;
                    tx_buf[1] = 0x01;
                    tx_buf[2] = 0x01;
                    tx_buf[3] = (byte) sync_total;
                    tx_buf[4] = (byte) (sync_total>>8);
                    write_bytes(tx_buf);//开始训练
                }
            }
        });
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

            }
        });
        dialog = builder.show();
    }

    public void sync_over(View view) {
        LayoutInflater factory = LayoutInflater.from(MainActivity.this);
        final View textEntryView = factory.inflate(R.layout.dialog, null);
        EditText tx_data1 = textEntryView.findViewById(R.id.et_tx1);
        EditText tx_data2 = textEntryView.findViewById(R.id.et_tx2);
        tx_data1.setInputType(InputType.TYPE_CLASS_NUMBER);
        tx_data2.setInputType(InputType.TYPE_CLASS_NUMBER);
        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
        builder.setTitle("请输入");
        builder.setIcon(android.R.drawable.ic_dialog_info);
        builder.setView(textEntryView);
        builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (!tx_data1.getText().toString().isEmpty() && !tx_data2.getText().toString().isEmpty()) {
                    byte sync_id = (byte) byteToUnsignedInt(Byte.parseByte(tx_data1.getText().toString()));
                    int sync_total = Integer.parseInt(tx_data2.getText().toString());
                    byte[] tx_buf = new byte[5];
                    tx_buf[0] = (byte) 0xAA;
                    tx_buf[1] = 0x02;
                    tx_buf[2] = 0x01;
                    tx_buf[3] = (byte) sync_total;
                    tx_buf[4] = (byte) (sync_total>>8);
                    write_bytes(tx_buf);//开始训练
                }
            }
        });
        builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {

            }
        });
        dialog = builder.show();
    }

    private void write_bytes(byte[] data){
        final BleDevice bleDevice =  (BleDevice) ScanBleList.get(spinner_ble_scan.getSelectedItemPosition());
        final String bleDevice_Mac = bleDevice.getMac();
        BleManager.getInstance().write(bleDevice, M_UART_SERVICE, M_UART_SERVICE_WRITE, data, new BleWriteCallback() {
            @Override
            public void onWriteSuccess(int current, int total, byte[] justWrite) {
                // 发送数据到设备成功（分包发送的情况下，可以通过方法中返回的参数可以查看发送进度）
                Log.d(TAG,"bleTxData：0x"+bytesToHexString(justWrite));
            }
            @Override
            public void onWriteFailure(BleException exception) {
                // 发送数据到设备失败
                Log.d(TAG,"bleTxData："+"发送失败");
            }
        });

    }
    public int byteToUnsignedInt(byte byt){
        return (int)(byt&0xff);
    }
    public static final String bytesToHexString(byte[] bArray) {
        StringBuffer sb = new StringBuffer(bArray.length);
        String sTemp;
        for (int i = 0; i < bArray.length; i++) {
            sTemp = Integer.toHexString(0xFF & bArray[i]);
            if (sTemp.length() < 2)
                sb.append(0);
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }

}